package com.tf_cut.backend.platform.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.google.common.collect.Lists;
import com.tf_cut.backend.common.pojo.PageInfo;
import com.tf_cut.backend.common.pojo.Result;
import com.tf_cut.backend.platform.service.RechargeService;
import com.tf_cut.backend.platform.vo.RechargeVo;
import com.tf_cut.backend.seller.service.SellerAccountDetailService;
import com.tf_cut.backend.seller.service.SellerAccountService;
import com.tf_cut.backend.seller.service.SellerOrderService;
import com.tf_cut.backend.seller.service.SellerRefAgentService;
import com.tf_cut.backend.seller.vo.SellerAccountDetailVo;
import com.tf_cut.backend.seller.vo.SellerAndAccountVo;
import com.tf_cut.backend.seller.vo.SellerOrderVo;
import com.tf_cut.backend.seller.vo.SellerRefAgentVo;
import com.tf_cut.backend.util.MoneyUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.List;

@Slf4j
@RestController
@RequestMapping("/backend/admin/platform/recharge")
public class RechargeController {

    @Autowired
    private RechargeService rechargeService;
    @Autowired
    private SellerAccountService sellerAccountService;
    @Autowired
    private SellerRefAgentService sellerRefAgentService;
    @Autowired
    private SellerOrderService sellerOrderService;
    @Autowired
    private SellerAccountDetailService sellerAccountDetailService;

    @PostMapping("/list")
    public String queryPlatformRechargeList(String json) {
        RechargeVo rechargeVo = JSON.parseObject(json, RechargeVo.class);
        Result<List<RechargeVo>> result;
        try {
            PageInfo<RechargeVo> rechargeVoList = rechargeService.queryRechargeList(rechargeVo);
            return JSON.toJSONString(rechargeVoList, SerializerFeature.WriteDateUseDateFormat);
        } catch (Exception e) {
            log.error("queryPlatformRechargeList error:{}", e.getMessage(), e);
            result = Result.of(Lists.newArrayList());
            result.setMsg(e.getMessage());
            result.setFlag(false);
        }
        return JSON.toJSONString(result, SerializerFeature.WriteDateUseDateFormat);
    }

    @PostMapping("/update")
    public Result<String> updatePlatformRecharge(@RequestBody RechargeVo rechargeVo) {
        Result<String> result = Result.of("修改成功");
        try {
            rechargeVo.setPage(1);
            rechargeVo.setRows(1);
            rechargeVo.setId(rechargeVo.getId());
            PageInfo<RechargeVo> rechargeVoList = rechargeService.queryRechargeList(rechargeVo);
            List<RechargeVo> list = rechargeVoList.getRows();
            if(CollectionUtils.isNotEmpty(list)){
                if("1".equals(rechargeVo.getStatus())){
                    RechargeVo retRecharge = list.get(0);

                    BigDecimal serverAmountPoint = new BigDecimal(0);//MoneyUtil.moneydiv(qrySellerServerAmountPoint(retRecharge.getSellerId()),new BigDecimal(100));
                    BigDecimal serviceAmount = new BigDecimal(0);//MoneyUtil.moneyMul(serverAmountPoint, retRecharge.getAmount());
                    BigDecimal rechargeBalAmt = MoneyUtil.moneySub(retRecharge.getAmount(), serviceAmount);

                    SellerAndAccountVo sellerAndAccountVo = SellerAndAccountVo.builder().sellerId(retRecharge.getSellerId()).build();
                    SellerAndAccountVo retSellerAndAccountVo = sellerAccountService.findSellerAccountByCondition(sellerAndAccountVo);
                    generateSellerChargeDetail(retRecharge,rechargeBalAmt,"05","0003",retSellerAndAccountVo,rechargeVo.getMerchantNumber(),rechargeVo.getPlatform());
//                    generateSellerChargeDetail(retRecharge,serviceAmount,"03","0002");


                    /*
                       2020-11-06 上传凭证时直接计算并扣除服务费
                       新增费用明细：类型为支出-服务费
                     */
//                    BigDecimal serverAmountPoint_ = MoneyUtil.moneydiv(qrySellerServerAmountPoint(retRecharge.getSellerId()),new BigDecimal(100));
//                    BigDecimal serviceAmount_ = MoneyUtil.moneyMul(serverAmountPoint_, retRecharge.getAmount());
//                    generateSellerAccountDetailToServiceAmount(retRecharge,"05",serviceAmount_,retSellerAndAccountVo.getSellerAccountId(),rechargeVo.getMerchantNumber(),rechargeVo.getPlatform());


                    //updateSellerBalance(retRecharge.getSellerId(),retRecharge.getAmount(),serverAmountPoint);
                }
                rechargeService.updateRecharge(rechargeVo);
            }else{
                log.warn("id={},不存在充值记录",rechargeVo.getId());
            }
        } catch (Exception e) {
            result.setMsg("更新充值状态失败");
            result.setFlag(false);
            result.setData("修改失败");
            log.error("updatePlatformRecharge error:{}", e.getMessage(), e);
        }
        return result;
    }

    /**
     * 生成明细
     * cpm_base_subject，科目表
     * @param retRecharge
     */
    private void generateSellerChargeDetail(RechargeVo retRecharge,BigDecimal amount,String orderSource,String paySubject,SellerAndAccountVo retSellerAndAccountVo,String merchantNumber,String platform) {
//        Result<SellerOrderVo> retSellerOrder = generateSellerOrderVoResult(retRecharge,amount);
        generateSellerAccountDetail(retRecharge,null,orderSource,paySubject,amount,retSellerAndAccountVo.getSellerAccountId(),merchantNumber,platform);
    }

    private Result<SellerOrderVo> generateSellerOrderVoResult(RechargeVo retRecharge,BigDecimal amount) {
        SellerOrderVo sellerOrderVo = new SellerOrderVo();
        sellerOrderVo.setSellerId(retRecharge.getSellerId());
        sellerOrderVo.setSellerName(retRecharge.getCompanyName());
        sellerOrderVo.setServiceId(retRecharge.getServiceId());
        sellerOrderVo.setServiceName(retRecharge.getServiceCenter());
        sellerOrderVo.setEndTime(Timestamp.valueOf(LocalDateTime.now()));
        sellerOrderVo.setRealAmount(amount);
        sellerOrderVo.setOrderType(0);
        return sellerOrderService.save(sellerOrderVo);
    }

    private void generateSellerAccountDetail(RechargeVo retRecharge,String orderId,String orderSource,String paySubject,BigDecimal amount,String sellerAccountId,String merchantNumber,String platform) {
        Timestamp now = Timestamp.valueOf(LocalDateTime.now());
        SellerAccountDetailVo sellerAccountDetailVo = new SellerAccountDetailVo();
        sellerAccountDetailVo.setSellerId(retRecharge.getSellerId());
        sellerAccountDetailVo.setSellerAccountId(sellerAccountId);
        sellerAccountDetailVo.setServiceId(retRecharge.getServiceId());
        sellerAccountDetailVo.setTradeSerial(retRecharge.getId());
        sellerAccountDetailVo.setOrderSource(orderSource);
        sellerAccountDetailVo.setOperType(1);
        sellerAccountDetailVo.setPayTime(now);
        sellerAccountDetailVo.setPaySubject(paySubject);
        sellerAccountDetailVo.setPayType(1);
        sellerAccountDetailVo.setTradeMoney(amount);
        sellerAccountDetailVo.setTradeComment(retRecharge.getComments());
        sellerAccountDetailVo.setIsTotal("N");
        sellerAccountDetailVo.setTotalTime(now);
//        sellerAccountDetailVo.setCpmTime(now);
//        sellerAccountDetailService.save(sellerAccountDetailVo);
        sellerAccountDetailService.insert(sellerAccountDetailVo,merchantNumber,platform);
    }

    private void generateSellerAccountDetailToServiceAmount(RechargeVo retRecharge,String paySubject,BigDecimal amount,String sellerAccountId,String merchantNumber,String platform) {
        Timestamp now = Timestamp.valueOf(LocalDateTime.now());
        SellerAccountDetailVo sellerAccountDetailVo = new SellerAccountDetailVo();
        sellerAccountDetailVo.setSellerId(retRecharge.getSellerId());
        sellerAccountDetailVo.setSellerAccountId(sellerAccountId);
        sellerAccountDetailVo.setServiceId(retRecharge.getServiceId());
        sellerAccountDetailVo.setTradeSerial(retRecharge.getId());
        sellerAccountDetailVo.setOrderSource("03");            //服务费类型
        sellerAccountDetailVo.setOperType(-1);
        sellerAccountDetailVo.setPayTime(now);
        sellerAccountDetailVo.setPaySubject(paySubject);
        sellerAccountDetailVo.setPayType(1);
        sellerAccountDetailVo.setTradeMoney(amount);
        sellerAccountDetailVo.setTradeComment("");
        sellerAccountDetailVo.setIsTotal("N");
        sellerAccountDetailVo.setTotalTime(now);
//        sellerAccountDetailService.save(sellerAccountDetailVo);
        sellerAccountDetailService.insert(sellerAccountDetailVo,merchantNumber,platform);
    }

    private void updateSellerBalance(String sellerId, BigDecimal rechargeAmount,BigDecimal serverAmountPoint) {
        SellerAndAccountVo sellerAndAccountVo = new SellerAndAccountVo();
        sellerAndAccountVo.setSellerId(sellerId);
        List<SellerAndAccountVo> sellerAndAccountList = sellerAccountService.list(sellerAndAccountVo).getData();
        if (CollectionUtils.isNotEmpty(sellerAndAccountList)) {
            SellerAndAccountVo retSellerAndAccountVo = sellerAndAccountList.get(0);
            setSellerAccountTotal(rechargeAmount, retSellerAndAccountVo,serverAmountPoint);
            setSellerServerAmount(rechargeAmount, retSellerAndAccountVo,serverAmountPoint);
            setAllGrantAmount(sellerId,retSellerAndAccountVo);
            setRechargeAmount(retSellerAndAccountVo);
            sellerAccountService.save(retSellerAndAccountVo);
        }
    }

    /**
     * 充值金额
     * 充值金额 = 服务费扣除 + 累计发放 + 账户总余额
     * @param retSellerAndAccountVo
     */
    private void setRechargeAmount(SellerAndAccountVo retSellerAndAccountVo) {
        BigDecimal one = MoneyUtil.moneyAdd(retSellerAndAccountVo.getServerAmount(),retSellerAndAccountVo.getGrantTotal());
        BigDecimal rechargeAmount = MoneyUtil.moneyAdd(one,retSellerAndAccountVo.getAccountTotal());
        retSellerAndAccountVo.setInvestTotal(rechargeAmount);
    }

    /**
     * 累计发放
     * @param sellerId
     * @param retSellerAndAccountVo
     */
    private void setAllGrantAmount(String sellerId,SellerAndAccountVo retSellerAndAccountVo) {
        SellerOrderVo sellerOrderVo = new SellerOrderVo();
        sellerOrderVo.setSellerId(sellerId);
        Result<BigDecimal> allGrant = sellerOrderService.calSellerGrantAmount(sellerOrderVo);
        retSellerAndAccountVo.setGrantTotal(allGrant.getData());
    }

    /**
     * 累计服务费
     * @param rechargeAmount
     * @param retSellerAndAccountVo
     * @param serverAmountPoint
     */
    private void setSellerServerAmount(BigDecimal rechargeAmount, SellerAndAccountVo retSellerAndAccountVo,BigDecimal serverAmountPoint) {
        BigDecimal serviceAmount = MoneyUtil.moneyMul(serverAmountPoint, rechargeAmount);
        BigDecimal allServerAmount = MoneyUtil.moneyAdd(serviceAmount, retSellerAndAccountVo.getServerAmount());
         /*
           2020-11-06 上传凭证时直接计算并扣除服务费
         */
        retSellerAndAccountVo.setServerAmount(allServerAmount);
        //retSellerAndAccountVo.setServerAmount(new BigDecimal(0));
    }

    /**
     * 账户总余额
     * @param rechargeAmount
     * @param retSellerAndAccountVo
     * @param serverAmountPoint
     */
    private void setSellerAccountTotal(BigDecimal rechargeAmount, SellerAndAccountVo retSellerAndAccountVo,BigDecimal serverAmountPoint) {
        BigDecimal serviceAmount = new BigDecimal(0);//MoneyUtil.moneyMul(serverAmountPoint, rechargeAmount);
        BigDecimal rechargeBalAmt = MoneyUtil.moneySub(rechargeAmount, serviceAmount);
        BigDecimal balance = MoneyUtil.moneyAdd(rechargeBalAmt, retSellerAndAccountVo.getAccountTotal());
        retSellerAndAccountVo.setAccountTotal(balance);
    }

    private BigDecimal qrySellerServerAmountPoint(String sellerId) {
        SellerRefAgentVo svo = SellerRefAgentVo.builder().sellerId(sellerId).build();
        svo.setPage(1);
        svo.setRows(10);
        PageInfo<SellerRefAgentVo> listSellerRefAgent = sellerRefAgentService.findListSellerRefAgent(svo);
        if (!listSellerRefAgent.getRows().isEmpty()) {
            List<SellerRefAgentVo> rows1 = listSellerRefAgent.getRows();
            log.info("sellerId={},sellerRefAgent size={}", sellerId, rows1.size());
            BigDecimal serverAmountPoint = rows1.get(0).getServerAmountPoint();
            return serverAmountPoint;
        }else{
            log.warn("未找到签约点数,sellerId={}",sellerId);
        }
        return null;
    }
    
    
	@RequestMapping("queryByMoney")
	public List<RechargeVo> queryByMoney(@RequestParam("sellerName") String sellerName){
		
		return rechargeService.queryByMoney(sellerName);
	}
	
	@RequestMapping("export")
	public List<RechargeVo> queryRechargeExportList(@RequestParam("sellerName") String sellerName){
		
		return rechargeService.queryRechargeExportList(sellerName);
	}
}
